package cn.gdrj.est.service.impl;

import cn.gdrj.est.constants.Constants;
import cn.gdrj.est.constants.ResultEnum;
import cn.gdrj.est.dto.MaintainOrderDTO;
import cn.gdrj.est.dto.ModelDetailDTO;
import cn.gdrj.est.dto.PayOrderDTO;
import cn.gdrj.est.exception.BusinessException;
import cn.gdrj.est.service.MaintainOrderService;
import cn.gdrj.est.service.ModelService;
import cn.gdrj.est.service.PayOrderService;
import cn.gdrj.est.service.PayService;
import cn.gdrj.est.util.AlipayProperties;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Map;

/**
 * TODO(这里用一句话描述这个类的作用)
 *
 * @author jun
 * @date 2021/11/16
 */
@Service
public class AliPayServiceImpl implements PayService {
    private static final Logger log = LoggerFactory.getLogger(AliPayServiceImpl.class);

    @Autowired
    private MaintainOrderService maintainOrderService;
    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private ModelService modelService;
    @Autowired
    private AlipayProperties alipayProperties;
    /**
     * 支付定金
     *
     * @param orderNo
     * @return
     * @throws Exception
     */
    @Override
    public String paySubscription(String orderNo) throws Exception {
        MaintainOrderDTO maintainOrderDTO = maintainOrderService.getByOrderNo(orderNo);
        // 如果订单号不存在
        if(ObjectUtils.isEmpty(maintainOrderDTO)){
            throw new BusinessException(ResultEnum.FAIL_HAVE_NOT_EXIST);
        }
        // 如果订单的定金已经支付
        Integer status = maintainOrderDTO.getStatus();
        if(ObjectUtils.nullSafeEquals(status, Constants.Order.MaintainStatus.PAY_DEPOSIT)){
            throw new BusinessException(ResultEnum.FAIL_PAY_DEPOSIT);
        }
        // 创建支付订单
        String maintainOrderNo = maintainOrderDTO.getOrderNo();
        PayOrderDTO payOrderDTO = new PayOrderDTO();
        payOrderDTO.setOrderNo(maintainOrderNo);
        // 因为一个维修单可能会发生多次支付，所以在每次支付的时候，生成不同的支付订单编号
        // 支付订单编号 = 维修订单编号 + 5位随机数字
        String payNo = generatePayNo(maintainOrderNo);
        payOrderDTO.setPayNo(payNo);
        payOrderDTO.setPayChannel(Constants.Order.Channel.ALIPAY);
        // 支付类型（1:定金,2:尾款
        payOrderDTO.setPayType(1);
        payOrderDTO.setUserId(maintainOrderDTO.getUserId());
        payOrderDTO.setPrice(maintainOrderDTO.getSubscription());

        payOrderService.savePayOrder(payOrderDTO);

        // 向支付发起支付的请求
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(),
                alipayProperties.getMerchantPrivateKey(),
                "json",
                alipayProperties.getCharset(),
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getSignType());
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        // 同步回调地址
        alipayRequest.setReturnUrl(alipayProperties.getReturnUrl());
        // 异步回调地址
        alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());

        JSONObject jsonObject =new JSONObject();
        jsonObject.set("out_trade_no",payNo);
        jsonObject.set("total_amount",payOrderDTO.getPrice().toString());
        // 华为mate10-维修定金
        Long modelId = maintainOrderDTO.getModelId();
        ModelDetailDTO modelDetailDTO = modelService.getById(modelId);

        // jsonObject.append("subject",modelDetailDTO.getModelName()+"-维修定金");
        jsonObject.set("subject","华为mate10-维修定金");
        jsonObject.set("body","");
        jsonObject.set("product_code","FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizContent(jsonObject.toString());

        String result = alipayClient.pageExecute(alipayRequest).getBody();
        log.debug(result);
        return result;
    }

    @Override
    public String aliPayNotify(Map<String, String> params) throws AlipayApiException {
        boolean signVerified = isSignVerified(params);
        // 验签失败的时候
        if(!signVerified){
            return "fail";
        }
        // 根据支付订单号查询支付订单的状态，只要不是未支付的状态，就直接返回success
        String payNo = params.get("out_trade_no");
        PayOrderDTO payOrderDTO = payOrderService.getByPayNo(payNo);
        if(!ObjectUtils.nullSafeEquals(payOrderDTO.getStatus(), Constants.Order.PayStatus.UN_PAY)){
            return "success";
        }
        // 根据支付订单号修改支付订单的状态
        String tradeNo = params.get("trade_no");
        payOrderService.updateOrderStatusToSuccess(payOrderDTO.getId(),tradeNo);
        // 修改维修订单的状态为已支付定金,添加维修订单状态变化的流水记录
        maintainOrderService.updateOrderStatusToPayed(payOrderDTO.getOrderNo());
        // 返回success
        return "success";
    }

    public boolean isSignVerified(Map<String, String> params) throws AlipayApiException {
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params,
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getCharset(),
                alipayProperties.getSignType());
        return signVerified;
    }

    private String generatePayNo(String maintainOrderNo) {
        return maintainOrderNo + RandomUtil.randomNumbers(5);
    }
}
